
package com.filetransfer.command;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.filetransfer.cache.CacheManager;
import com.filetransfer.client.batchtransfer.BatchTransferClient;
import com.filetransfer.client.batchtransfer.EdenSendCallBack;
import com.filetransfer.client.scan.FileFolderScan;
import com.filetransfer.client.scan.callback.EdenScanCallBack;
import com.filetransfer.client.singlesend.SingleSendClient;
import com.filetransfer.client.state.TransferControl;
import com.filetransfer.client.state.TransferState;
import com.filetransfer.config.FileClientConfig;
import com.filetransfer.config.ReceiveFileMessageConfig;
import com.filetransfer.eis.FileInfo;
import com.filetransfer.plugin.AuthorityClientFilePlugin;
import com.filetransfer.plugin.DemoClientFilePlugin;
import com.filetransfer.server.message.ReceiveFileMessageCallBack;
import com.filetransfer.server.message.ReceiveFileMessagePulse;
import com.filetransfer.server.message.callback.EdenReceiveFileMessageCallBack;
import com.filetransfer.transport.command.FileInfoMessage;
import com.filetransfer.util.ExceptionUtil;
import com.filetransfer.util.LogUtil;
import com.filetransfer.util.StringUtil;

/**
 * 功能说明:  <br>
 * 开发人员: hanxuetong <br>
 * 开发时间: 2014-9-24 <br>
 * ======== ====== ============================================ <br>
 * 
 */
public class FileTransferClient {

	private boolean isInited=false;//是否启动初始化了
	private FileClientConfig clientConfig;	
	private TransferControl transferControl;
	private FileFolderScan fileFolderScan;
	/**
	 * 中转传输时监听发送到目标主机消息的回调
	 */
	private ReceiveFileMessageCallBack receiveFileMessageCallBack;
	
	public FileTransferClient(FileClientConfig clientConfig)
	{
		if(!StringUtil.isAllNotEmpty(clientConfig))
		{
			ExceptionUtil.throwException("FileTransferClient的clientConfig不能为null");
			
		}
		this.setClientConfig(clientConfig);
		
		transferControl=new TransferControl(clientConfig);

	}
	
	/**
	 * 启动初始化,替换相关回调函数要在它执行之前
	 */
	public void init()
	{
		initMessageListener();
		initMonitor();
		
		//异常退出关闭
		Runtime.getRuntime().addShutdownHook(new Thread(){                                        
              public void run(){ 
                  //添入你想在退出JVM之前要处理的必要操作代码
            	 // manager.shutdown();
            	  CacheManager.stop();
                   System.out.println("===========================退出时关闭了cacheManager===================================");
               }
		});
		
		isInited=true;
			
		
	}
	
	/**
	 * 启动文件监控
	 */
	private void initMonitor()
	{
		if(clientConfig.isMonitor())
		{
			transferControl.init();
			//initMessageListener();
			fileFolderScan=new FileFolderScan(transferControl);
			initTimerTask();
		}
	
	}
	
	/**
	 * 启动定时扫描
	 */
	private void initTimerTask()
	{
		Timer timer = new Timer();
		    //设置任务计划，启动和间隔时间
		timer.schedule(new ScanFileTask(),1000,transferControl.getClientConfig().getTimerTaskPeriod());
		
	}
	/**
	 * 启动发送到目标主机消息的监听
	 */
	private void initMessageListener()
	{
		if(clientConfig.isTransit()) //中转传输才进行
		{
			if(receiveFileMessageCallBack==null)
			{
				receiveFileMessageCallBack=new EdenReceiveFileMessageCallBack(transferControl);
				
			}	
			//启动消息接收
			ReceiveFileMessageConfig receiveFileMessageConfig=new ReceiveFileMessageConfig(clientConfig.getReceiveMsgPort(), receiveFileMessageCallBack);
			ReceiveFileMessagePulse receiveFileMessagePulse=new ReceiveFileMessagePulse(receiveFileMessageConfig);
			receiveFileMessagePulse.start();
		}
		
	}
	
	/**
	 * 扫描文件传输
	 */
	public void scan()
	{
		checkInit();
		if(clientConfig.isMonitor())
		{

			if(transferControl.getTransferState().isTransferEnd())
			{
				fileFolderScan.startScan();
				
			}else{
				
				LogUtil.echo("现在正在文件传输中");
			}
		}else{
			LogUtil.err("当前配置为不监控文件夹，不能进行扫描！");
		}
	
	}
	
	/**
	 * 定时执行任务类
	 *
	 */
	public class ScanFileTask extends TimerTask
	{

		
		@Override
		public void run() {

			FileTransferClient.this.scan();
		
		}
		
		
	}
	/**
	 * 发送单文件
	 * @param wantFilePath
	 * @param fileInfo
	 */
	public void sendFile(String wantFilePath,FileInfo fileInfo)
	{
		checkInit();
		createSingleSendClient().sendFile(wantFilePath, fileInfo);
	}
	/**
	 * 发送单文件
	 * @param wantFilePath
	 * @param fileInfo
	 * @param sendToIp
	 * @param sendToPort
	 */
	public void sendFile(String wantFilePath,FileInfo fileInfo,String sendToIp,Integer sendToPort)
	{
		checkInit();
		createSingleSendClient().sendFile(wantFilePath, fileInfo, sendToIp, sendToPort);
	}
	/**
	 * 发送单文件
	 * @param wantFilePath
	 * @param fileInfo
	 * @param sendToIp
	 * @param sendToPort
	 * @param targetIp
	 * @param targetPort
	 */
	public void sendFile(String wantFilePath,FileInfo fileInfo,String sendToIp,Integer sendToPort,String targetIp,Integer targetPort)
	{
		checkInit();
		createSingleSendClient().sendFile(wantFilePath, fileInfo, sendToIp, sendToPort, targetIp, targetPort);
		
	}
	/**
	 * 发送单文件
	 * @param fileInfoMessage
	 */
	public void sendFile(FileInfoMessage fileInfoMessage)
	{
		checkInit();
		createSingleSendClient().sendFile(fileInfoMessage);
	}
	
	/**
	 * 批量发送文件
	 * @param fileList
	 */
	public void sendBatchFile(List<FileInfoMessage> fileList)
	{
		checkInit();
		if(fileList!=null)
		{
			for(FileInfoMessage fileInfoMessage:fileList)
			{
				sendFile(fileInfoMessage);
			}
		}else{
			LogUtil.err("fileList为null，不能发送文件。。");
		}
		
	}
	
	/**
	 * 创建单文件发送组件
	 * @return
	 */
	private SingleSendClient createSingleSendClient()
	{
		SingleSendClient singleTransferClient=new SingleSendClient(transferControl.getClientConfig(),transferControl.getSendCallBack());
		singleTransferClient.setTransferControl(transferControl);
		return singleTransferClient;
	}
	/**
	 * 查看有没有初始化
	 */
	private void checkInit()
	{
		if(!isInited)
		{
			
			LogUtil.err("FileTransferClient 还未初始化！");
			ExceptionUtil.throwException("FileTransferClient 还未初始化！");
			
		}
		
	}
	
	public FileClientConfig getClientConfig() {
		return clientConfig;
	}

	public void setClientConfig(FileClientConfig clientConfig) {
		this.clientConfig = clientConfig;
	}

	public TransferControl getTransferControl() {
		return transferControl;
	}

	public void setTransferControl(TransferControl transferControl) {
		this.transferControl = transferControl;
	}
	
	
	public ReceiveFileMessageCallBack getReceiveFileMessageCallBack() {
		return receiveFileMessageCallBack;
	}
	public void setReceiveFileMessageCallBack(ReceiveFileMessageCallBack receiveFileMessageCallBack) {
		this.receiveFileMessageCallBack = receiveFileMessageCallBack;
	}
	
	
	public static void main(String[] args) {
		
		/*Thread th=new Thread(){

			@Override
			public void run() {
				try {
					Thread.sleep(10000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				while(true)
				{
					try {
					Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					System.out.println("刷新缓存");
					CacheManager.flush("cache1345810216");
				}
			
				
				
				
			
			}
			
		};
		th.start();*/
		//System.setProperty("net.sf.ehcache.enableShutdownHook","true");
		//批量监控传输
/*		FileClientConfig clientConfig=new FileClientConfig("E:\\upload", true, true, true, "localhost", 111,"localhost",112,201);
		clientConfig.setTimerTaskPeriod(1000*30);
		clientConfig.setAuthorityCheck(true);//权限验证
		clientConfig.setAuthorityKey("password111"); //验证密锁
		FileTransferClient fileTransferClient=new FileTransferClient(clientConfig);
		fileTransferClient.getTransferControl().addClientFilePlugin(new DemoClientFilePlugin(fileTransferClient.getTransferControl()));
		fileTransferClient.getTransferControl().addClientFilePlugin(new AuthorityClientFilePlugin(fileTransferClient.getTransferControl())); //添加验证拦截器
		fileTransferClient.init();*/
		
		//不中转监控传输
	/*	FileClientConfig clientConfig=new FileClientConfig("E:\\upload",true,true,false,"localhost",111);
		clientConfig.setTimerTaskPeriod(1000*30);
		clientConfig.setAuthorityCheck(true);//权限验证
		clientConfig.setAuthorityKey("password111"); //验证密锁
		FileTransferClient fileTransferClient=new FileTransferClient(clientConfig);
		fileTransferClient.getTransferControl().addClientFilePlugin(new DemoClientFilePlugin(fileTransferClient.getTransferControl()));//拦截器demo
		fileTransferClient.getTransferControl().addClientFilePlugin(new AuthorityClientFilePlugin(fileTransferClient.getTransferControl())); //添加验证拦截器
		fileTransferClient.init();*/
		
		
	
		
	/*	//发送单文件中转时
		FileClientConfig clientConfig=new FileClientConfig(false,true,true,"localhost",111,"localhost",112,201);
		clientConfig.setAuthorityCheck(true);//权限验证
		clientConfig.setAuthorityKey("password111"); //验证密锁
		FileTransferClient fileTransferClient=new FileTransferClient(clientConfig);
		fileTransferClient.getTransferControl().addClientFilePlugin(new DemoClientFilePlugin(fileTransferClient.getTransferControl()));//拦截器demo
		fileTransferClient.getTransferControl().addClientFilePlugin(new AuthorityClientFilePlugin(fileTransferClient.getTransferControl())); //添加验证拦截器
		 fileTransferClient.init();
		
		 //要发送的文件
		String absolutePath="E:\\upload\\22 - 副本.docx";
		FileInfo fileInfo=new FileInfo();
    	fileInfo.setFilePath(absolutePath);
		fileTransferClient.sendFile("\\hhd\\22.docx", fileInfo); //想保存的文件名
*/		

		//发送单文件不中转时
		
		
		FileClientConfig clientConfig=new FileClientConfig(false,true,false,"localhost",112);
/*		clientConfig.setAuthorityCheck(true);//权限验证
		clientConfig.setAuthorityKey("password111"); //验证密锁
*/		FileTransferClient fileTransferClient=new FileTransferClient(clientConfig);
		EdenSendCallBack edenSendCallBack=new EdenSendCallBack(fileTransferClient.getTransferControl()); //回调
		fileTransferClient.getTransferControl().setSendCallBack(edenSendCallBack);
		 fileTransferClient.init();

		 //要发送的文件
		String absolutePath="E:\\temp\\log\\localhost_access_log.2015-08-25.txt";
		FileInfo fileInfo=new FileInfo();
    	fileInfo.setFilePath(absolutePath);
		fileTransferClient.sendFile("\\log\\localhost_access_log.2015-08-25.txt", fileInfo); //想保存的文件名
		 //要发送的文件
		absolutePath="E:\\temp\\log\\localhost_access_log.2015-08-27.txt";
		FileInfo fileInfo2=new FileInfo();
		fileInfo2.setFilePath(absolutePath);
		fileTransferClient.sendFile("\\log\\localhost_access_log.2015-08-27.txt", fileInfo2); //想保存的文件名
	}
	
}
